﻿// This file is part of Code4Public (http://code4public.codeplex.com)
// Copyright 2011 Sina Iravanian - <sina@sinairv.com>
//
// This source file(s) may be redistributed, altered and customized
// by any means PROVIDING the authors name and all copyright
// notices remain intact.
// THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED. USE IT AT YOUR OWN RISK. THE AUTHOR ACCEPTS NO
// LIABILITY FOR ANY DATA DAMAGE/LOSS THAT THIS PRODUCT MAY CAUSE.
// ------------------------------------------------------------------

using System;
using System.Text;
using System.Drawing;
using Code4Public.Utils;
using YAXLib;

namespace Code4Public.Settings
{
    public class Theme : ICloneable
    {
        [YAXAttributeFor(".#name")]
        public string Name { get; set; }

        [YAXElementFor("Header#Border")]
        public BorderInfo HeaderBorder { get; set; }

        [YAXElementFor("Header#Font")]
        public FontInfo HeaderFont { get; set; }

        [YAXAttributeFor("Header/BackColor#value")]
        [YAXCustomSerializer(typeof(ColorSerializer))]
        public Color HeaderBackColor { get; set; }

        [YAXAttributeFor("Header/FontSize#value")]
        public int HeaderFontSize { get; set; }

        [YAXElementFor("MainContent#Border")]
        public BorderInfo MainContentBorder { get; set; }
        
        [YAXAttributeFor("MainContent/FontSize#value")]
        public int MainContentFontSize { get; set; }

        [YAXAttributeFor("LineNumbers/SeperatorLine#show")]
        public bool LineNumbersShowSeperatorLine { get; set; }

        [YAXAttributeFor("LineNumbers/SeperatorLine#color")]
        [YAXCustomSerializer(typeof(ColorSerializer))]
        public Color LineNumbersSeperatorLineColor { get; set; }

        [YAXElementFor("LineNumbers#Font")]
        public FontInfo LineNumbersFont { get; set; }
        
        [YAXCustomSerializer(typeof(ColorSerializer))]
        [YAXAttributeFor("LineNumbers/BackColor#value")]
        public Color LineNumbersBackColor { get; set; }

        [YAXAttributeFor("LineNumbers/ShowZeros#value")]
        public bool LineNumbersShowZeros { get; set; }

        [YAXAttributeFor("LineNumbers/CharAfterLineNo#show")]
        public bool LineNumbersShowStringAfter { get; set; }

        [YAXAttributeFor("LineNumbers/CharAfterLineNo#value")]
        public string LineNumbersStringAfter { get; set; }

        [YAXAttributeFor("LineNumbers/SpacesAfter#count")]
        public int LineNumbersSpacesAfter { get; set; }

        [YAXAttributeFor("LineNumbers/SpacesBefore#count")]
        public int LineNumbersSpacesBefore { get; set; }

        [YAXCustomSerializer(typeof(ColorSerializer))]
        [YAXAttributeFor("CodeContent/BackColor#value")]
        public Color CodeContentBackColor { get; set; }

        [YAXElementFor("CodeContent#Font")]
        public FontInfo CodeContentFont { get; set; }

        #region Construction

        public Theme()
            : this("[NoName]")
        {
            
        }

        public Theme(string name)
        {
            Name = name;

            LoadDefaultValues();
        }

        private void LoadDefaultValues()
        {
            HeaderBorder = CodeConstants.Theme.HeaderBorderDefault;
            HeaderFont = CodeConstants.Theme.HeaderFontDefault;
            HeaderBackColor = CodeConstants.Theme.HeaderBackColorDefault;
            HeaderFontSize = CodeConstants.Theme.HeaderFontSizeDefault;

            MainContentBorder = CodeConstants.Theme.MainContentBorderDefault;
            MainContentFontSize = CodeConstants.Theme.MainContentFontSizeDefault;

            LineNumbersShowSeperatorLine = CodeConstants.Theme.LineNumbersShowSeperatorLineDefault;
            LineNumbersSeperatorLineColor = CodeConstants.Theme.LineNumbersSeperatorLineColorDefault;
            LineNumbersFont = CodeConstants.Theme.LineNumbersFontDefault;
            LineNumbersBackColor = CodeConstants.Theme.LineNumbersBackColorDefault;
            LineNumbersShowZeros = CodeConstants.Theme.LineNumbersShowZerosDefault;
            LineNumbersShowStringAfter = CodeConstants.Theme.LineNumbersShowStringAfterDefault;
            LineNumbersStringAfter = CodeConstants.Theme.LineNumbersStringAfterDefault;
            LineNumbersSpacesAfter = CodeConstants.Theme.LineNumbersSpacesAfterDefault;
            LineNumbersSpacesBefore = CodeConstants.Theme.LineNumbersSpacesBeforeDefault;

            CodeContentBackColor = CodeConstants.Theme.CodeContentBackColorDefault;
            CodeContentFont = CodeConstants.Theme.CodeContentFontDefault;
        }

        #endregion

        public override string ToString()
        {
            return Name;
        }

        #region ICloneable Members

        public object Clone()
        {
            var newTheme = (Theme)MemberwiseClone();

            newTheme.HeaderBorder = (BorderInfo)HeaderBorder.Clone();
            newTheme.HeaderFont = (FontInfo)HeaderFont.Clone();
            newTheme.MainContentBorder = (BorderInfo)MainContentBorder.Clone();
            newTheme.LineNumbersFont = (FontInfo)LineNumbersFont.Clone();
            newTheme.CodeContentFont = (FontInfo)CodeContentFont.Clone();

            return newTheme;
        }

        #endregion
    }

    public class BorderInfo : ICloneable
    {
        public BorderInfo()
        {
            Top = false;
            Bottom = false;
            Left = false;
            Right = false;
            Color = AppSettings.Settings.DefaultTextColor;
        }

        [YAXAttributeFor(".#top")]
        public bool Top { get; set; }

        [YAXAttributeFor(".#bottom")]
        public bool Bottom { get; set; }

        [YAXAttributeFor(".#left")]
        public bool Left { get; set; }

        [YAXAttributeFor(".#right")]
        public bool Right { get; set; }

        [YAXCustomSerializer(typeof(ColorSerializer))]
        [YAXAttributeFor(".#color")]
        public Color Color { get; set; }

        public override string ToString()
        {
            var sb = new StringBuilder();

            sb.Append(ColorUtils.ColorTo6CharHtmlString(Color) + " ");
            if(Top)
                sb.Append("Top ");

            if(Right)
                sb.Append("Right ");

            if(Bottom)
                sb.Append("Bottom ");

            if(Left)
                sb.Append("Left ");

            return sb.ToString();
        }

        #region ICloneable Members

        public object Clone()
        {
            var newBorderInfo = (BorderInfo)this.MemberwiseClone();
            return newBorderInfo;
        }

        #endregion
    }

    public class FontInfo : ICloneable
    {
        public FontInfo()
        {
            Bold = false;
            Italic = false;
            Color = AppSettings.Settings.DefaultTextColor;
        }

        public FontInfo(Color color, bool bold, bool italic)
        {
            Bold = bold;
            Italic = italic;
            Color = color;
        }

        [YAXAttributeFor(".#bold")]
        public bool Bold { get; set; }

        [YAXAttributeFor(".#italic")]
        public bool Italic { get; set; }

        [YAXCustomSerializer(typeof(ColorSerializer))]
        [YAXAttributeFor(".#color")]
        public Color Color { get; set; }

        public override string ToString()
        {
            return String.Format("{0}, {1}, {2}", ColorUtils.ColorTo6CharHtmlString(Color), Bold, Italic);
        }

        #region ICloneable Members

        public object Clone()
        {
            var newFontInfo = (FontInfo) MemberwiseClone();
            return newFontInfo;
        }

        #endregion
    }
}
